package org.example.Thread.B_Thread;

import java.util.concurrent.*;

/**
 * @className: getCount
 * @author: 芃
 * @description: 多线程环境下数组求和
 * @date: 2024/5/13 15:59
 */
public class getCount {
    public static final int[] arr = {1,2,3,4,5,6,7,8,9,10};
    public static int index = 0;
    public static int length = arr.length;
    public static Object locker = new Object();

    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3);
        Callable<Integer> callable1 = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int sum = 0;
                while(index < length){
                    synchronized(locker){
                        if (index < length){
                            Thread.sleep(1000);
                            sum += arr[index++];
                        }
                    }
                }
                return sum;
            }
        };
        Callable<Integer> callable2 = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int sum = 0;
                while(index < length){
                    synchronized(locker){
                        if (index < length){
                            Thread.sleep(1000);
                            sum += arr[index++];
                        }
                    }
                }
                return sum;
            }
        };
        Callable<Integer> callable3 = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int sum = 0;
                while(index < length){
                    synchronized(locker){
                        if (index < length){
                            Thread.sleep(1000);
                            sum += arr[index++];
                        }
                    }
                }
                return sum;
            }
        };

        /*
         * @executor.submit 方法，是拿到callable实例，直接去线程池获取线程，然后把callable实例交给线程去执行，并将最终的执行结果封装到Future对象中，
         * 最后返回Future对象，通过Future对象可以获取到callable的执行结果。
         */
        Future<Integer> task1 = executor.submit(callable1);
        Future<Integer> task2 = executor.submit(callable2);
        Future<Integer> task3 = executor.submit(callable3);
        try {
            System.out.println(task1.get() + " " + task2.get() + " " +  task3.get());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
    }
}
